package net.jcip.examples.chapter7;

import java.io.IOException;
import java.net.Socket;
import java.util.concurrent.*;

import net.jcip.annotations.*;

/**
 * SocketUsingTask
 * <p/>
 * Encapsulating nonstandard cancellation in a task with newTaskFor
 *
 * @author Brian Goetz and Tim Peierls
 */

public abstract class SocketUsingTask <T> implements CancellableTask<T> {
    @GuardedBy("this") private Socket socket;

    protected synchronized void setSocket(Socket s) {
        socket = s;
    }

    public synchronized void cancel() {
        try {
            if (socket != null)
                socket.close();
        } catch (IOException ignored) {
        }
    }

    public RunnableFuture<T> newTask() {
        //this：在 new FutureTask<T>(this) 中，this 是 SocketUsingTask<T> 的当前实例。
        return new FutureTask<T>(this) {
            public boolean cancel(boolean mayInterruptIfRunning) {
                try {
                    //SocketUsingTask.this：
                    // 在匿名内部类中，通过 SocketUsingTask.this 引用外部类 SocketUsingTask 的当前实例，这是为了避免引用冲突，并确保调用的是外部类的 cancel 方法。
                    SocketUsingTask.this.cancel();
                } finally {
                    return super.cancel(mayInterruptIfRunning);
                }
            }
        };
    }
}

/**
 * Callable 接口是 Java 并发包中的一个接口，它类似于 Runnable，但是比 Runnable 更强大，因为它可以返回一个结果并且可以抛出一个受检异常。
 * Callable 通常与 Future 一起使用，用于异步任务的执行和结果获取。
 * @param <T>
 */
interface CancellableTask <T> extends Callable<T> {
    void cancel();

    RunnableFuture<T> newTask();
}


/**
 * 具体逻辑
 * 检查 callable 是否是 CancellableTask 的实例：
 *
 * if (callable instanceof CancellableTask) 检查传入的 Callable<T> 是否实现了 CancellableTask 接口。
 * CancellableTask 是一个扩展了 Callable<T> 的接口，并且提供了额外的取消功能。
 * 创建 CancellableTask 对应的 RunnableFuture 实例：
 *
 * 如果 callable 是 CancellableTask 的实例，则调用 ((CancellableTask<T>) callable).newTask()。
 * 这会调用 CancellableTask 的 newTask 方法，返回一个 RunnableFuture<T> 实例，该实例具有定制的取消行为。
 * 创建普通的 RunnableFuture 实例：
 *
 * 如果 callable 不是 CancellableTask 的实例，则调用 super.newTaskFor(callable)。
 * 这会调用 ThreadPoolExecutor 类的 newTaskFor 方法，创建一个标准的 FutureTask<T> 实例
 */
@ThreadSafe
class CancellingExecutor extends ThreadPoolExecutor {
    public CancellingExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }

    public CancellingExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
    }

    public CancellingExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
    }

    public CancellingExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
    }

    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        if (callable instanceof CancellableTask)
            return ((CancellableTask<T>) callable).newTask();
        else
            return super.newTaskFor(callable);
    }
}
